/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bionic.ce.logic;

import com.bionic.ce.entities.Currency;
import com.bionic.ce.entities.Query;
import com.bionic.ce.entities.User;
import com.bionic.ce.entitybeans.currency.CurrencyFacadeLocal;
import com.bionic.ce.entitybeans.query.QueryFacadeLocal;
import com.bionic.ce.entitybeans.systemacc.SystemaccFacadeLocal;
import com.bionic.ce.entitybeans.user.UserFacadeLocal;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.EJBs;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 *
 * @author Jarik
 */
@EJBs({
    @EJB(name = "UsersFacadeLoc", beanInterface = UserFacadeLocal.class),
    @EJB(name = "CurrencyFacadeLoc", beanInterface = CurrencyFacadeLocal.class),
    @EJB(name = "QueryFacadeLoc", beanInterface = QueryFacadeLocal.class),
    @EJB(name = "SystemAccFacadeLoc", beanInterface = SystemaccFacadeLocal.class)
})

//класс бизнес логики для анализа и обмена существуюзих заявок
public class QueriesService {

    private static CurrencyFacadeLocal currencyEJB = null;
    private static UserFacadeLocal userEJB = null;
    private static SystemaccFacadeLocal systemAccEJB = null;
    private static QueryFacadeLocal queryEJB = null;
    private static Query query = null;

    // проверка на окончание срока действия заявки
    public static void expirationCheck() {
        queryEJB = lookupQueryFacadeLocal();
        query = new Query();
        query.setStatus("Active");
        List<Query> list = queryEJB.findByDynamicSelect(query);
        for (Query q : list) {
            if ((q.getFinishDate()).before(new Date())) {
                q.setStatus("Expired");
                queryEJB.edit(q);
            }
        }
    }
    //возвращает список активных заявок (если нужно для даного пользователя то нужен параметр Id)
    public static List<Query> check(Integer userId) {
        queryEJB = lookupQueryFacadeLocal();
        userEJB = lookupUsersFacadeLocal();
        expirationCheck();
        query = new Query();
        if (userId!=null){
        User user = userEJB.findById(userId);
        query.setOpenByUser(user);}
        query.setStatus("Active");
        List<Query> list = queryEJB.findByDynamicSelect(query);
        return list;
    }
    //возвращает сумму заявок для даного пользователя (userId) по конкретной валюте (currencyFrom)
    public static Double balancecheck(Integer userId, String currencyFrom) {
        queryEJB = lookupQueryFacadeLocal();
        currencyEJB = lookupCurrencyFacadeLocal();
        userEJB = lookupUsersFacadeLocal();
        Double sum = 0.0;
        query = new Query();
        query.setStatus("Active");
        User user = userEJB.findById(userId);
        query.setOpenByUser(user);
        Currency currency = currencyEJB.findByShortName(currencyFrom);
        query.setCurrencyFrom(currency);
        List<Query> list = queryEJB.findByDynamicSelect(query);
        for (Query q : list) {
            sum += q.getAmount();
        }
        return sum;
    }
    //метод для обмена заявок в автоматическом режиме
    public static Double autoExchange(Query query) {
        queryEJB = lookupQueryFacadeLocal();
        systemAccEJB = lookupSystemAccFacadeLocal();

        Double d = null;

        Query searchQuery = new Query();
        searchQuery.setCurrencyFrom(query.getCurrencyTo());
        searchQuery.setCurrencyTo(query.getCurrencyFrom());
        searchQuery.setStatus("Active");
        List<Query> searchlist = queryEJB.findByDynamicSelect(searchQuery);
        Double minAm = (double) ((int) Math.round((query.getAmount() * query.getRateFrom()) * 1000)) / 1000;
        Double maxAm = (double) ((int) Math.round((query.getAmount() * query.getRateTo()) * 1000)) / 1000;

        if (!searchlist.isEmpty()) {
            for (Query searchQ : searchlist) {
                Double searchminAm = (double) ((int) Math.round((searchQ.getAmount() * searchQ.getRateFrom()) * 1000)) / 1000;
                Double searchmaxAm = (double) ((int) Math.round((searchQ.getAmount() * searchQ.getRateTo()) * 1000)) / 1000;
                if (searchQ.getAmount() >= minAm & searchQ.getAmount() <= maxAm
                        & query.getAmount() >= searchminAm & query.getAmount() <= searchmaxAm) {
                    systemAccEJB.executedQueryMoneyTransfer(query.getOpenByUser(), query.getCurrencyFrom(), query.getCurrencyTo(), searchQ.getOpenByUser(), query.getAmount(), searchQ.getAmount());
                    query.setStatus("Executed By System");
                    Double closedRate = (double) ((int) Math.round((searchQ.getAmount() / query.getAmount()) * 1000)) / 1000;
                    query.setClosedRate(closedRate);
                    query.setClosedDate(new Date());
                    query.setExecutedByUser(searchQ.getOpenByUser());
                    queryEJB.edit(query);

                    searchQ.setStatus("Executed By System");
                    closedRate = (double) ((int) Math.round((query.getAmount() / searchQ.getAmount()) * 1000)) / 1000;
                    searchQ.setClosedRate(closedRate);
                    searchQ.setClosedDate(new Date());
                    searchQ.setExecutedByUser(query.getOpenByUser());
                    queryEJB.edit(searchQ);

                   d = searchQ.getAmount();
                    break;
                }
            }
        }
        return d;
    }

    private static CurrencyFacadeLocal lookupCurrencyFacadeLocal() {
        try {
            Context c = new InitialContext();
            return (CurrencyFacadeLocal) c.lookup("java:comp/env/CurrencyFacadeLoc");
        } catch (NamingException ex) {
            Logger.getLogger(QueriesService.class.getName()).log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex);
        }
    }

    private static UserFacadeLocal lookupUsersFacadeLocal() {
        try {
            Context c = new InitialContext();
            return (UserFacadeLocal) c.lookup("java:comp/env/UsersFacadeLoc");
        } catch (NamingException ex) {
            Logger.getLogger(QueriesService.class.getName()).log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex);
        }
    }

    private static SystemaccFacadeLocal lookupSystemAccFacadeLocal() {
        try {
            Context c = new InitialContext();
            return (SystemaccFacadeLocal) c.lookup("java:comp/env/SystemAccFacadeLoc");
        } catch (NamingException ex) {
            Logger.getLogger(QueriesService.class.getName()).log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex);
        }
    }

    private static QueryFacadeLocal lookupQueryFacadeLocal() {
        try {
            Context c = new InitialContext();
            return (QueryFacadeLocal) c.lookup("java:comp/env/QueryFacadeLoc");
        } catch (NamingException ex) {
            Logger.getLogger(QueriesService.class.getName()).log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex);
        }
    }
}
